/**
 * Created by Arnald on 2017/5/10.
 */
const schedule = require('node-schedule');
const variable = require('../config/variable.js');
const msg = require('../util/msg.js');
const log = require('../util/log.js');
const util = require('../util/util.js');
const request = require('../util/request.js');
var mem = require('../util/mem.js');

var timeoutA = variable.config.timeoutA * 1000;
var timeoutB = variable.config.timeoutB * 1000;

module.exports = interval;

function interval() {
    // 建立一个时间循环的默认规则
    var rule = new schedule.RecurrenceRule();
    // 增加一个每秒执行的内容
    var times = [];
    for (var i = 1; i < 60; i++) {
        times.push(i);
    }
    rule.second = times;
    // 开始动作
    schedule.scheduleJob(rule, function () {
        // 排队循环
        lineUp();
        // 检查排队时长
        timeOut();
    });
}

// 排队事件
function lineUp() {
    if (playerCount() <= 1) {
        return false;
    }
    // 用户分组，把不同等级的用户放到不同的组里
    var groups = {};
    var lvsGroup = false;
    var lvsNum = 0;
    for (var i in playerLists()) {
        if (!playerLists(i) || playerLists(i).lock == true) {
            continue;
        }
        // 以等级作为分组基准
        //var lv = Math.floor(playerLists(i).lv / variable.groupLevel);
        var lv = Math.floor(playerLists(i).gameLv);
        if (!groups[lv]) {
            groups[lv] = [];
            lvsNum++;
        }
        groups[lv].push(i);
    }
    if (lvsNum < 1) {
        return false;
    }
    // 把不同组里的用户配给房间
    for (var i in groups) {
        // 如果组里不够3人则跳过
        if (groups[i].length < 3) {
            continue;
        }
        matchRoom(groups[i], i);
    }
}

// 检查排队超时
function timeOut() {
    if (playerCount() <= 0) {
        return false;
    }
    var time = Date.now();
    for (var i in playerLists()) {
        if (!playerLists(i)) {
            continue;
        }
        if (!playerLists(i)) {
            continue;
        }
        if (!playerLists(i).lock) {
            var c = time - playerLists(i).linkTime;
            if (c > timeoutB) {
                msg.send(playerLists(i).cid, playerLists(i).uuid, 'matchEnd');
                delete mem.matchPlayers[i];
                continue;
            }
            if (c > timeoutA) {
                if (variable.config.robotTurnOn) {
                    robotRoom(i);
                } else {
                    msg.send(playerLists(i).cid, playerLists(i).uuid, 'matchOut');
                }
            }
        }
    }
}

function playerCount() {
    return Object.keys(mem.matchPlayers).length;
}

// 获取一个用户的信息
function playerLists(id) {
    if (!id) {
        return mem.matchPlayers;
    }
    if (!mem.matchPlayers[id]) {
        mem.matchPlayers[id] = {};
    }
    return mem.matchPlayers[id];
}

function matchRoom(group, i) {
    //从组里取出3个人
    var selected = getRandomArrayElements(group, 3);
    // 整理取出的3个人的资料发给房间服务器
    var userList = [];
    for (var j in selected) {
        if (!playerLists(selected[j])) {
            continue;
        }
        playerLists(selected[j]).lock = true;
        userList.push(selected[j]);
    }
    var data = {};
    data.user = [];
    data.lv = i;
    for (var j in userList) {
        var userInfo = util.userInfo(playerLists(userList[j]).user);
        userInfo.uuid = playerLists(userList[j]).uuid;
        data.user.push(userInfo);
    }
    request.createRoom(data, function (result) {
        createRoomCB(result, userList);
    });
}

function robotRoom(id) {
    var userList = [];
    playerLists(id).lock = true;
    userList.push(id);
    var data = {};
    data.user = [];
    data.lv = playerLists(id).gameLv;
    for (var j in userList) {
        var userInfo = util.userInfo(playerLists(userList[j]).user);
        userInfo.uuid = playerLists(userList[j]).uuid;
        data.user.push(userInfo);
    }
    request.getRobot(data.lv,function (result) {
        if (result.code != 200) {
            setTimeout(function () {
                for (var j in userList) {
                    playerLists(userList[j]).lock = false;
                }
            }, 5000);
            log.d('暂时没有机器人，5秒后再试');
            return false;
        }
        var robotIds = result.robotId;
        for (var j in robotIds) {
            var userInfo = util.userInfo(robotIds[j]);
            userInfo.robot = true;
            data.user.push(userInfo);
        }
        request.createRoom(data, function (result1) {
            createRoomCB(result1, userList);
        });
    });
}

function createRoomCB(result, userList) {
    if (result.code == 404) {
        for (var j in userList) {
            playerLists(userList[j]).lock = false;
        }
        log.d('房间服务器连接失败');
        return false;
    }
    if (result.code == 102) {
        var ids = [];
        for (var j in result.inGameId) {
            ids.push(j);
        }
        for (var j in userList) {
            if (ids.indexOf(userList[j]) >= 0) {
                msg.send(playerLists(userList[j]).cid, playerLists(userList[j]).uuid, 'matchInGame', {
                    'userId': userList[j],
                    'gameId': result.inGameId[userList[j]].gameId,
                    'local': result.inGameId[userList[j]].local,
                    'gameType': result.inGameId[userList[j]].gameType
                });
                delete mem.matchPlayers[userList[j]];
            } else {
                playerLists(userList[j]).lock = false;
            }
        }
        return false;
    }
    if (result.code == 103) {
        var ids = [];
        for (var j in result.errId) {
            ids.push(j);
        }
        for (var j in userList) {
            if (ids.indexOf(userList[j]) >= 0) {
                msg.send(playerLists(userList[j]).cid, playerLists(userList[j]).uuid, 'error', {'code': 10028});
                delete mem.matchPlayers[userList[j]];
            } else {
                playerLists(userList[j]).lock = false;
            }
        }
        return false;
    }
    if (result.code == 200) {
        var key = result.key;
        for (var j in userList) {
            var local = result.player[userList[j]];
            msg.send(playerLists(userList[j]).cid, playerLists(userList[j]).uuid, 'matchGame', {
                'userId': userList[j],
                'gameId': key,
                'local': local
            });
            delete mem.matchPlayers[userList[j]];
        }
        log.p('room:' + key + ',data:' + JSON.stringify(result));
    }
}


function getRandomArrayElements(arr, count) {
    var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
    while (i-- > min) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(min);
}
